package billingServer;


import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import common.rmi.RemoteBillingServerSecure;

public class BillingServerSecure extends UnicastRemoteObject implements RemoteBillingServerSecure{
	
	private static final long serialVersionUID = 1L;

	private PriceSteps priceSteps = new PriceSteps(); 
	private Bill bill = new Bill();
	private Lock lockAddPriceStep = new ReentrantLock();
	private Lock lockDeletePriceStep = new ReentrantLock();
	
	protected BillingServerSecure() throws RemoteException {
		super();
	}

	public void createPriceStep(double startPrice, double endPrice, double fixedPrice, double variablePricePercent) throws RemoteException 
	{
		boolean res = true;
		String errMsg = "";
		
		if ((startPrice < 0) || (endPrice < 0))
		{
			res = false;
			errMsg = "Wrong price value";
		}
		else
		{
			lockAddPriceStep.lock();
			for (int i = 0; i < priceSteps.data.size(); i++)
			{
				if (((priceSteps.data.get(i).MinPrice <= endPrice) || (endPrice == 0)) &&
					((priceSteps.data.get(i).MaxPrice >= startPrice) || (priceSteps.data.get(i).MaxPrice == 0)))
				{
					res = false;
					errMsg = "The selected range has been occupied before";
					break;
				}
			}
			
			if (res)
			{
				PriceStep priceStep = new PriceStep();
				priceStep.MinPrice = startPrice;
				priceStep.MaxPrice = endPrice;
				priceStep.FixedPrice = fixedPrice;
				priceStep.VariablePricePercent = variablePricePercent;
				priceSteps.data.add(priceStep);
			}
			lockAddPriceStep.unlock();
		}
		
		if (!res)
			throw new RemoteException(errMsg);
	}


	public PriceSteps getPriceSteps() throws RemoteException 
	{
		return priceSteps;
	}


	public void deletePriceStep(double startPrice, double endPrice)	throws RemoteException 
	{
		boolean res = false;
		String errMsg = "The specified step wasn't founded";
		
		lockDeletePriceStep.lock();
		int i;
		for (i = 0; i < priceSteps.data.size(); i++)
		{
			if ((priceSteps.data.get(i).MinPrice == startPrice) && (priceSteps.data.get(i).MaxPrice == endPrice))
			{
				res = true;
				break;
			}
		}
		if (res)
		{
			priceSteps.data.remove(i);
		}
		lockDeletePriceStep.unlock();
		
		if (!res)
			throw new RemoteException(errMsg);
	}


	public void billAuction(String user, long auctionID, double price) throws RemoteException 
	{
		BillItem billItem = new BillItem();
		billItem.UserName = user;
		billItem.AuctionID = auctionID;
		billItem.AuctionPrice = price;
		billItem.CalculatedFixedPrice = 0.0;
		billItem.CalculatedVariablePrice = 0.0;
		bill.data.add(billItem);
	}


	public Bill getBill(String user) throws RemoteException 
	{
		Bill billForUser = new Bill();
		
		for (int i = 0; i < bill.data.size(); i++)
		{
			if (bill.data.get(i).UserName.compareTo(user) == 0)
			{
				for (int j = 0; j < priceSteps.data.size(); j++)
				{
					if ((bill.data.get(i).AuctionPrice >= priceSteps.data.get(j).MinPrice) &&
					    (bill.data.get(i).AuctionPrice <= priceSteps.data.get(j).MaxPrice))
					{
						bill.data.get(i).CalculatedFixedPrice = priceSteps.data.get(j).FixedPrice;
						bill.data.get(i).CalculatedVariablePrice = (priceSteps.data.get(j).VariablePricePercent * bill.data.get(i).AuctionPrice) /100;
						break;
					}
				}
				billForUser.data.add(bill.data.get(i));
			}
		}
		
		return billForUser;
	}
}
